"""
@Project:${2108a 人工智能}
@File:users.py
@Author:周家昌
@Date:9:46
"""

from flask_restful import Api,Resource,reqparse,marshal,fields
from sqlalchemy import or_
from celery_tasks.tasks import sms_code
from common.models.users import *
from werkzeug.security import generate_password_hash,check_password_hash
from common.utils.token_utils import _generate_token
from common.utils.custom_resp_json import custom_json
from common.utils.login_auth import login_auth

from flask import Blueprint,jsonify, request ,make_response
import redis
import random
from io import BytesIO
import string
from captcha.image import ImageCaptcha
from common.utils.captcha import Captcha





user_bp = Blueprint('user_bp',__name__,url_prefix='/user')
api = Api(user_bp)

@api.representation('application/json')
def output_json(data, code, headers=None):
    resp = custom_json(data, code, headers=None)
    return resp
# 发送验证码
class send_Code(Resource):
    def get(self):
        parse = reqparse.RequestParser()
        parse.add_argument('phone')
        args = parse.parse_args()
        mobile = args['phone']
        code = random.randint(1000,9999)
        print('----',code)
        res = sms_code(mobile,code)
        print('----',res)

        r = redis.Redis(host='localhost',port=6379,db=2)
        key = 'sms_code:%s'%mobile
        r.set(key,code,ex=60*10)
        return jsonify(code= 200, msg= '短信已发送，注意查收')

# 注册
class Register(Resource):
    def post(self):
        parse = reqparse.RequestParser()
        parse.add_argument('username')
        parse.add_argument('password')
        parse.add_argument('phone')
        parse.add_argument('code')
        parse.add_argument('password2')
        args = parse.parse_args()
        uname = args['username']
        password = args['password']
        mobile = args['phone']
        code = args['code']
        password2 = args['password2']
        user = UserModel.query.filter_by(uname=uname).first()
        if not user:
            user2 = UserModel.query.filter_by(mobile=mobile).first()
            if not user2:
                r = redis.Redis(host='localhost', port=6379, db=2)
                key = 'sms_code:%s' % mobile
                r_code = r.get(key).decode()
                if r_code == code:
                    password = generate_password_hash(password)
                    try:
                        user = UserModel(account=uname,password=password,mobile=mobile)
                        db.session.add(user)
                        db.session.commit()
                        return jsonify(code= 200,msg= '注册成功')
                    except Exception as e:
                        print(e)
                        return jsonify(code=400, msg='注册失败')
                else:
                    return jsonify(code= 400, msg='验证码错误')
            else:
                return jsonify(code= 400, msg='手机号已被注册')
        else:
            return jsonify(code= 400, msg= '用户已存在')


class ImageCode(Resource):
    def get(self):
        # uuid = request.args.get('uuid')
        # alpha_number = string.ascii_letters + string.digits # 生成一串数字和字母构成的字符串
        # img_code = ''.join(random.sample(alpha_number, 4)) # 从字符串中抽取四个字符
        # # 生成验证码图片
        # image = ImageCaptcha(80, 40) #  生成空白图片 宽和高
        # color = tuple([random.randint(0, 255) for i in range(3)])
        # background = tuple([random.randint(0, 255) for i in range(3)])
        #               # 空白图片加上验证码，字体颜色元组，背景颜色元组
        # img = image.create_captcha_image(img_code, color=color, background=background)
        # print('>>>>>>>>', uuid)
        # if uuid:
        #     r = redis.Redis(db=2, host='localhost', port=6379, password='zjcnb')
        #     key = 'imgcode:%s' % uuid
        #     r.set(key, img_code, 120)
        #     file = BytesIO()   # 能从缓存中读取二进制数据
        #     img.save(file,'png') # 将图片验证码保存到file
        #
        #     response = make_response(file.getvalue())
        #     print(file.getvalue())
        #     response.headers["Content-Type"] = "image/png"  # 类型为图片
        #     return response
        uuid = request.args.get('uuid') # 接收uuid
        captcha = Captcha()  # 创建对象
        (text,image) = captcha.gene_graph_captcha() # 调用方法获取验证码和图片验证码
        if uuid:
            r = redis.Redis(db=2, host='localhost', port=6379)
            key = 'imgcode:%s' % uuid
            r.set(key,text, 120)    # 将验证码存入redis

            out = BytesIO()   # 能从缓存中读取二进制数据
            image.save(out,'png')  # 将图片验证码保存到out
                             # 读取图片的文件流
            resp = make_response(out.getvalue())        # 自定义返回格式
            resp.headers["Content-Type"] = "image/png"   # 类型指定为图片
            return resp


class Login(Resource):
    def post(self):
        parse = reqparse.RequestParser()
        parse.add_argument('account')
        parse.add_argument('password')
        parse.add_argument('uuid')
        parse.add_argument('img_code')
        args = parse.parse_args()
        uuid = args['uuid']
        account = args['account']
        password = args['password']
        img_code = args['img_code']
        user = UserModel.query.filter(or_(UserModel.account==account,UserModel.mobile==account)).first()
        if user:
            r = redis.Redis(db=2, host='localhost', port=6379)
            key = 'imgcode:%s' % uuid
            code = r.get(key).decode()
            print('---------',code)
            if str(code).lower() == str(img_code).lower():
                res = check_password_hash(user.password,password)
                if res:
                    token,refresh_token = _generate_token(user)
                    return jsonify(code= 200, msg= '登录成功',data={'token':token,'uid':user.uid,'account':user.account,'refresh':refresh_token,'img':user.profile_photo})
                else:
                    return jsonify(code= 400, msg= '密码错误')
            else:
                return jsonify(code=400, msg='验证码错误')
        else:
            return jsonify(code= 400, msg= '用户不存在')

# 修改密码:
class up_password_code(Resource):
    def get(self):
        parse = reqparse.RequestParser()
        parse.add_argument('phone')
        args = parse.parse_args()
        phone = args['phone']
        user = UserModel.query.filter_by(mobile=phone).first()
        if user:

            code = random.randint(1000, 9999)
            print('----', code)
            res = sms_code.delay(phone, code)
            print('----', res)

            r = redis.Redis(host='localhost', port=6379, db=2)
            key = 'xg_sms_code:%s' % phone
            r.set(key, code, ex=60 * 10)
            return jsonify(code=200, msg='短信已发送 '+str(code))
        return jsonify(code=400,msg='该手机号用户不存在')
class Up_Password(Resource):
    def get(self):      # 验证验证码
        parse = reqparse.RequestParser()
        parse.add_argument('code')
        parse.add_argument('phone')
        args = parse.parse_args()
        code = args['code']
        phone = args['phone']
        user = UserModel.query.filter_by(mobile=phone).first()
        if user:
            r = redis.Redis(host='localhost', port=6379, db=2)
            key = 'xg_sms_code:%s' % phone
            res = r.get(key)
            if res:
                if res == code.encode():
                    return jsonify(code=200,msg='验证码正确')
                return jsonify(code=400, msg='验证码错误')
            return jsonify(code=400, msg='验证码不存在或已过期')
        return jsonify(code=401, msg='手机号不存在')
    def post(self):  # 修改密码
        parse = reqparse.RequestParser()
        parse.add_argument('password')
        parse.add_argument('phone')
        args = parse.parse_args()
        password = args['password']
        phone = args['phone']

        user = UserModel.query.filter_by(mobile=phone).first()
        res = check_password_hash(user.password,password)
        print('***',res)
        if res:
            return jsonify(code=400, msg='不可与原密码一致')
        try:
            password = generate_password_hash(password)
            UserModel.query.filter_by(mobile=phone).update({'password':password})
            db.session.commit()
            return jsonify(code=200, msg='修改密码成功')
        except:
            return jsonify(code=400, msg='修改密码失败')

user_fields = {
    'uid':fields.Integer,
    'uname':fields.String,
    'account':fields.String,
    'mobile':fields.String,
    'profile_photo':fields.String
}

class UserInfo(Resource):
    def get(self):
        parse = reqparse.RequestParser()
        parse.add_argument('uid')
        args = parse.parse_args()
        uid = args['uid']
        try:
            user = UserModel.query.get(uid)
            return jsonify(code=200,msg='获取用户信息成功',data=marshal(user,user_fields))
        except Exception as e:
            return jsonify(code=400,msg='获取用户信息失败')











api.add_resource(send_Code,'/phone_code')
api.add_resource(Register,'/register_user')
api.add_resource(ImageCode,'/code')
api.add_resource(Login,'/login')
api.add_resource(Up_Password,'/up_password')
api.add_resource(up_password_code,'/up_password_code')
api.add_resource(UserInfo,'/get_user')







